Ndertimi i modeleve dhe klasave te tjera
Pa perfundimit te shabllonit statik HTML dhe CSS, eshte e nevojshme konvertimi ne nje faqe dinamike pasi ne gjendjen aktuale nuk do te na sherbente per gje. Do te perdorim programimin e orientuar nga objekti per te kryer nje sere funksionesh dinamike si p.sh. bashkeveprimi me bazen e te dhenave, apo autentikimi i perdoruesit ne hyrje, lidhja me databazen etj.
Implementimi i klasave
Klasat e direktorise libs
Database
eshte nje klase shpjeguar edhe ne seksionet e meparshme. Luan rolin per lidhjen me bazen e te dhenave dhe kryerjen e disa funksioneve te vecanta si:insert
- Shtim i nje rekordi ne bazen e te dhenaveupdate
- Modifikim i nje rekordiselect
- Lexim i rekordeve nga baza e te dhenavedelete
- Fshirje rekordesh nga baza e te dhenave
Me poshte paraqitet implementimi i plote i klases:
<?php
class Database {
private $connection;
function __construct() {
$host = "127.0.0.1"; //ose thjesht: localhost
$user = "c1_mesophp";
$password = "mesophp";
$db_name = "mesophp_db";
try {
$this->connection = new PDO("mysql:host=$host;dbname=$db_name", $user, $password);
// Vendosim metoden sesi PDO-ja do te gjeneroje gabimet - ne form Exception:
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $ex) {
echo "Lidhja deshtoi: " . $ex->getMessage();
exit;
}
}
public function insert(string $table, array $field_values) {
$fushat = implode(',', array_keys($field_values));
$parametrat = ':' . implode(', :', array_keys($field_values));
$stmt = $this->connection->prepare("INSERT INTO $table ($fushat) VALUES ($parametrat);");
foreach ($field_values as $key => $value) {
$stmt->bindValue(":$key", $value);
}
$rezultati = $stmt->execute();
if ($rezultati) {
$id = $this->connection->lastInsertId();
return $id;
} else {
$error = $stmt->errorInfo();
return $error;
}
}
public function update(string $table, array $field_values, string $where) {
$fushe_vlerat = null;
foreach ($field_values as $key => $value) {
$fushe_vlerat .= "$key = :$key,";
}
$fushe_vlerat = rtrim($fushe_vlerat, ',');
$stmt = $this->connection->prepare("UPDATE $table SET $fushe_vlerat WHERE $where");
foreach ($field_values as $key => $value) {
$stmt->bindValue(":$key", $value);
}
$rezultati = $stmt->execute();
if ($rezultati)
return $rezultati;
else
return $stmt->errorInfo();
}
public function select(string $sql, array $bindArray = array(), $fetchMode = PDO::FETCH_ASSOC) {
$stmt = $this->connection->prepare($sql);
foreach ($bindArray as $key => $value) {
$stmt->bindValue("$key", $value);
}
$stmt->execute();
return $stmt->fetchAll( $fetchMode );
}
public function delete(string $table, string $where, int $limit = 1) {
return $this->connection->exec("DELETE FROM $table WHERE $where LIMIT $limit");
}
}
AuthUser
do te jete pergjegjese per autentikimin e perdoruesve ne sistem ne momentin qe perdorin formen e logimit, si dhe permban funksione te ndryshme qe sherbejne per kontroll te autentikimit, ruatje, ose dalje nga sistemi. Me poshte paraqesim implementimin e kesaj klase dhe shpjegojme funksionet e saj kryesore.
<?php
require_once WEBROOT . "models/Perdorues.php";
class AuthUser
{
public static function authenticate(string $email, string $password)
{
$sql = "SELECT * FROM perdoruesit WHERE email = :email AND password = :password";
$db = new Database();
$rezultati = $db->select($sql, [
":email" => $email,
":password" => $password
]);
if (count($rezultati)) {
$perdorues = new Perdorues([
"emri" => $rezultati[0]["emri"],
"email" => $rezultati[0]["email"],
"tipi" => $rezultati[0]["tipi"],
"id_departament" => $rezultati[0]["id_departament"],
]);
$perdorues->setId($rezultati[0]["id"]);
return $perdorues;
} else {
return false;
}
}
public static function save(Array $perdorues)
{
Session::set("user_auth", $perdorues);
}
public static function is_logged()
{
if (is_null(self::get())) {
return false;
} else {
return true;
}
}
public static function logout()
{
Session::clear("user_auth");
}
public static function get()
{
return Session::get("user_auth");
}
}
Klasa AuthUser
eshte brenda direktorise libs
. Na duhet te bejme importimin e klases Perdorues
e cila ndodhet ne direktorine models
.
<?php
require_once WEBROOT . "models/Perdorues.php";
Eshte perdorur nje konstante e quajtur WEBROOT
per te na ndihmuar ne importimin e file-ve. Ne kete rast WEBROOT
eshte e nevojshme te kete vleren ../
, pra per te simbolizuar direktorine prind. WEBROOT
deklarohet tek nje file config.php
e cila vendoset brenda ne direktorine admin
, me permbajtjen e meposhtme:
<?php
define("WEBROOT", "../");
require_once WEBROOT . "libs/Session.php";
Session::start();
Pra, eshte deklaruar WEBROOT
me vleren ../
. Dicka tjeter e rendesishme qe behet ne kete file konfigurimi eshte nisja e sesionit te faqes. Ketu kemi perdorur librarine Session
te krijuar nga ne te cilen do ta sqarojme pak me poshte.
Ne te vertete logjika e sistemit tone qendron ne dy pjese, e para kemi faqe te aksesueshme nga cdo lloj vizitori te cilat ndodhen ne direktorine rrenje te projektit, dhe se dyti kemi faqe te aksesueshme nga perdorues te autentikuar te cilet ndodhen ne direktorine admin
. Per rastin e pare vlera e WEBROOT
duhet te jete boshe, pra ""
sepse importimi i file-ve vazhdon drejperdrejt ne direktorine rrenje p.sh.
<?php
require_once WEBROOT . "models/Perdorues.php";
eshte e njejte me:
<?php
require_once "models/Perdorues.php";
sepse jemi ne direktorine rrenje. Per kete arsye ne direktorine rrenje ekziston nje file tjeter config.php
me permbajtjen e meposhtme:
<?php
define("WEBROOT", "");
require_once WEBROOT . "libs/Session.php";
Session::start();
Ne skedaret e direktorise rrenje duhet te importojme kete file config.php
per konfigurim, ndersa ne skedaret e direktorise admin
duhet te importojme skedarin admin/config.php
per arsye se WEBROOT
duhet te marre vlere tjeter.
Shqyrtojme funksionin authenticate
te klases AuthUser
:
<?php
public static function authenticate(string $email, string $password)
{
$sql = "SELECT * FROM perdoruesit WHERE email = :email AND password = :password";
$db = new Database();
$rezultati = $db->select($sql, [
":email" => $email,
":password" => $password
]);
if (count($rezultati)) {
$perdorues = new Perdorues([
"emri" => $rezultati[0]["emri"],
"email" => $rezultati[0]["email"],
"tipi" => $rezultati[0]["tipi"],
"id_departament" => $rezultati[0]["id_departament"],
]);
$perdorues->setId($rezultati[0]["id"]);
return $perdorues;
} else {
return false;
}
}
Merr si parametra hyres $email
dhe $password
, perdor metoden select
te klases Database
per te ekzekutuar deklaraten SQL SELECT * FROM perdoruesit WHERE email = :email AND password = :password
. Ne rast se kthehet pergjigje pozitive, pra ekziston nje rekord me kredencialet e percaktuara, atehere kthehet mbrapsht nje instance e tipit Perdorues
. Kjo instance eshte vete perdoruesi i sapo autentikuar. Ne rast se kredencialet jane te gabuara do te kthehet false
.
Shqyrtojme funksionin save
:
<?php
public static function save(Array $perdorues)
{
Session::set("user_auth", $perdorues);
}
Merr ne hyrje nje array me te dhenat e perdoruesit, dhe e ruan ne sesion. Ky funksion perdoret ne menyre qe pas autentikimit perdoruesi te ruhet ne sesion dhe te mos jete e nevojshme qe cdo here te fuse kredencialet per te aksesuar nje faqe.
Shqyrtojme funksionin is_logged
:
<?php
public static function is_logged()
{
if (is_null(self::get())) {
return false;
} else {
return true;
}
}
Kontrollon nqs. ekziston nje sesion me perdorues te autentikuar, ne rast se po kthen true
, perndryshe kthen false
.
Shqyrtojme funksionin logout
:
<?php
public static function logout()
{
Session::clear("user_auth");
}
Qellimi i kesaj metode eshte te nxjerre perdoruesin jashte sistemit, duke e fshire sesionin qe mban perdoruesin e loguar.
Shqyrtojme funksionin get
:
<?php
public static function get()
{
return Session::get("user_auth");
}
Ne rast se ne sesion jane ruajtur te dhenat e perdoruesit te loguar, pra ne rast se ne sistem ka nje perdorues te loguar, ky funksion kthen te dhenat e tij, perndryshe kthen null
.
Session
do te jete pergjegjese per menaxhimin e sesioneve ne sistem si nisja e sesioneve, ruajtja, marrja apo fshirja e tyre. Me poshte paraqesim implementimin e kesaj klase dhe shpjegojme funksionet e saj kryesore.
<?php
class Session
{
public static function start()
{
session_start();
}
public static function set($key, $value)
{
$_SESSION[$key] = $value;
}
public static function get($key)
{
if (isset($_SESSION[$key]))
return $_SESSION[$key];
else
return null;
}
public static function clear($key)
{
unset($_SESSION[$key]);
}
public static function destroy()
{
session_destroy();
}
}
- Klasa
BaseModel
do te jete klase prind e te gjitha model-eve qe do te gjenden ne direktorinemodels
. Ajo ka permbajtjen e meposhtme:
<?php
require_once "Database.php";
class BaseModel {
protected $db;
function __construct() {
$this->db = new Database();
}
}
Sic e shohim, krijon nje instance te tipit Database
te cilen e trashegon secili nga modelet qe do te trashegoje kete klase. Me tej variabli $db
do te perdoret nga klasat femije per te bere thirrje te ndryshme ne bazen e te dhenave. Keto thirrje mundesohen nga klasa Database
.
Klasat e direktorise models
Ne seksionin e meparshem Menaxhimi i te dhenave me POO
kemi shpjeguar menyren sesi funksionon nje model dhe metodat kryesore te tij. Ne vijim do te implementojme te gjitha modelet e nevojshme duke u bazuar mbi te.
- Klasa
Departament
do te sherbeje per kryerjen e veprimeve te ndryshme mbi tabelendepartamentet
pra shtim, modifikim, lexim ose fshirje rekordesh me ane te metodave specifike. Implementimi i kesaj klase vijon me poshte:
<?php
require_once WEBROOT . 'libs/BaseModel.php';
class Departament extends BaseModel
{
private $id;
public $emri;
public $pershkrimi;
function __construct(array $dep = [])
{
parent::__construct();
$this->emri = isset($dep['emri']) ? $dep['emri'] : null;
$this->pershkrimi = isset($dep['pershkrimi']) ? $dep['pershkrimi'] : null;
}
public function getId()
{
return $this->id;
}
public function save()
{
if (is_null($this->id)) {
$new_id = $this->db->insert("departamentet", [
"emri" => $this->emri,
"pershkrimi" => $this->pershkrimi
]);
return $new_id;
} else {
$rezultati = $this->db->update("departamentet", [
"emri" => $this->emri,
"pershkrimi" => $this->pershkrimi
], "id = {$this->id}");
return $rezultati;
}
}
public function delete()
{
$rezultati = $this->db->delete("departamentet", "id = {$this->id}");
return $rezultati;
}
public static function getById(int $id)
{
$sql = "SELECT * FROM departamentet WHERE id = :id";
$db = new Database();
$rekord = $db->select($sql, [":id" => $id]);
// $rekord eshte nje array me listen e rekordeve qe u kthye
if (count($rekord)) {
// Nese ekziston rekord me kete id, krijojme nje objekt perfaqesues per te
$departament = new Departament();
$departament->id = $rekord[0]["id"];
$departament->emri = $rekord[0]["emri"];
$departament->pershkrimi = $rekord[0]["pershkrimi"];
return $departament;
} else {
return null;
}
}
public static function getList(string $condition = "1")
{
$sql = "SELECT * FROM departamentet WHERE $condition";
$db = new Database();
$rekordet = $db->select($sql);
// $rekordet eshte nje array me listen e rekordeve qe u kthye
$departamentet = []; //Ky array do te mbaje listen e objekteve te tipit `Artikull`
if (count($rekordet)) {
foreach ($rekordet as $rekord) {
//Per cdo rekord te kthyer nga databaza krijojme nje objekt:
$departament = new Departament();
$departament->id = $rekord["id"];
$departament->emri = $rekord["emri"];
$departament->pershkrimi = $rekord["pershkrimi"];
// E shtojme objektin e krijuar ne array-n kryesor:
array_push($departamentet, $departament);
}
//Kthejme listen e objekteve te tipit `Artikull`:
return $departamentet;
} else {
return array();
}
}
}
- Klasa
Perdorues
do te sherbeje per kryerjen e veprimeve te ndryshme mbi tabelenperdoruesit
pra shtim, modifikim, lexim ose fshirje rekordesh me ane te metodave specifike. Vec tyre ne kete klase kemi edhe disa metoda shtese. Implementimi i kesaj klase vijon me poshte:
<?php
require_once WEBROOT . 'libs/BaseModel.php';
class Perdorues extends BaseModel
{
private $id;
public $emri;
public $email;
public $password;
public $tipi = 1;
public $id_departament;
function __construct(array $user = [])
{
parent::__construct();
$this->emri = isset($user['emri']) ? $user['emri'] : null;
$this->email = isset($user['email']) ? $user['email'] : null;
$this->password = isset($user['password']) ? $user['password'] : null;
$this->tipi = isset($user['tipi']) ? $user['tipi'] : null;
$this->id_departament = isset($user['id_departament']) ? $user['id_departament'] : null;
}
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function save()
{
if (is_null($this->id)) {
$new_id = $this->db->insert("perdoruesit", [
"emri" => $this->emri,
"email" => $this->email,
"password" => $this->password,
"tipi" => $this->tipi,
"id_departament" => $this->id_departament
]);
return $new_id;
} else {
$rezultati = $this->db->update("perdoruesit", [
"emri" => $this->emri,
"email" => $this->email,
"password" => $this->password,
"tipi" => $this->tipi,
"id_departament" => $this->id_departament
], "id = {$this->id}");
return $rezultati;
}
}
public function delete()
{
$rezultati = $this->db->delete("perdoruesit", "id = {$this->id}");
return $rezultati;
}
public static function getById(int $id)
{
$sql = "SELECT * FROM perdoruesit WHERE id = :id";
$db = new Database();
$rekord = $db->select($sql, [":id" => $id]);
// $rekord eshte nje array me listen e rekordeve qe u kthye
if (count($rekord)) {
// Krijojme nje objekt perfaqesues per rekordin qe u kthye nga databaza
$perdorues = new Perdorues();
$perdorues->id = $rekord[0]["id"];
$perdorues->emri = $rekord[0]["emri"];
$perdorues->email = $rekord[0]["email"];
$perdorues->password = $rekord[0]["password"];
$perdorues->tipi = $rekord[0]["tipi"];
$perdorues->id_departament = $rekord[0]["id_departament"];
return $perdorues;
} else {
return null;
}
}
public static function getList(string $condition = "1")
{
$sql = "SELECT * FROM perdoruesit WHERE $condition";
$db = new Database();
$rekordet = $db->select($sql);
// $rekordet eshte nje array me listen e rekordeve qe u kthye
$perdoruesit = []; //Ky array do te mbaje listen e objekteve te tipit `Perdorues`
if (count($rekordet)) {
foreach ($rekordet as $rekord) {
//Per cdo rekord te kthyer nga databaza krijojme nje objekt:
$perdorues = new Perdorues();
$perdorues->id = $rekord["id"];
$perdorues->emri = $rekord["emri"];
$perdorues->email = $rekord["email"];
$perdorues->password = $rekord["password"];
$perdorues->tipi = $rekord["tipi"];
$perdorues->id_departament = $rekord["id_departament"];
// E shtojme objektin e krijuar ne array-n kryesor:
array_push($perdoruesit, $perdorues);
}
//Kthejme listen e objekteve te tipit `Perdorues`:
return $perdoruesit;
} else {
return array();
}
}
public function toArray() {
$perdorues = [];
$perdorues["id"] = $this->id;
$perdorues["emri"] = $this->emri;
$perdorues["email"] = $this->email;
$perdorues["password"] = $this->password;
$perdorues["tipi"] = $this->tipi;
$perdorues["id_departament"] = $this->id_departament;
return $perdorues;
}
public function isAdmin()
{
if ($this->tipi == 0) {
return true;
}
return false;
}
}
Metoda toArray
thjesht beh konvertimin e objektit aktual ne nje array dhe e kthen ate. Deklaron nje array $perdorues = [];
dhe me pas i jep vlere duke u bazuar mbi anetaret e objektit aktual $perdorues["id"] = $this->id;
. Kjo behet per te gjitha fushat e objektit dhe ne fund kthen array-n e ndertuar.
Metoda isAdmin
kontrollon tipin e perdoruesit dhe kthen true
nqs. tipi ka vleren 0 , pra $this->tipi == 0
, perndryshe kthen false
.
- Klasa
Njoftim
do te sherbeje per kryerjen e veprimeve te ndryshme mbi tabelennjoftimet
pra shtim, modifikim, lexim ose fshirje rekordesh me ane te metodave specifike. Implementimi i kesaj klase vijon me poshte:
<?php
require_once WEBROOT . 'libs/BaseModel.php';
class Njoftim extends BaseModel
{
private $id;
public $titulli;
public $pershkrimi;
public $data;
public $id_departament;
function __construct(array $njoft = [])
{
parent::__construct();
$this->titulli = isset($njoft['titulli']) ? $njoft['titulli'] : null;
$this->pershkrimi = isset($njoft['pershkrimi']) ? $njoft['pershkrimi'] : null;
$this->data = isset($njoft['data']) ? $njoft['data'] : null;
$this->id_departament = isset($njoft['id_departament']) ? $njoft['id_departament'] : null;
}
public function getId()
{
return $this->id;
}
public function save()
{
if (is_null($this->id)) {
$new_id = $this->db->insert("njoftimet", [
"titulli" => $this->titulli,
"pershkrimi" => $this->pershkrimi,
"data" => $this->data,
"id_departament" => $this->id_departament
]);
return $new_id;
} else {
$rezultati = $this->db->update("njoftimet", [
"titulli" => $this->titulli,
"pershkrimi" => $this->pershkrimi,
"data" => $this->data,
"id_departament" => $this->id_departament
], "id = {$this->id}");
return $rezultati;
}
}
public function delete()
{
$rezultati = $this->db->delete("njoftimet", "id = {$this->id}");
return $rezultati;
}
public static function getById(int $id)
{
$sql = "SELECT * FROM njoftimet WHERE id = :id";
$db = new Database();
$rekord = $db->select($sql, [":id" => $id]);
// $rekord eshte nje array me listen e rekordeve qe u kthye
if (count($rekord)) {
// Nese ekziston rekord me kete id, krijojme nje objekt perfaqesues per te
$njoftim = new Njoftim();
$njoftim->id = $rekord[0]["id"];
$njoftim->titulli = $rekord[0]["titulli"];
$njoftim->pershkrimi = $rekord[0]["pershkrimi"];
$njoftim->data = $rekord[0]["data"];
$njoftim->id_departament = $rekord[0]["id_departament"];
return $njoftim;
} else {
return null;
}
}
public static function getList(string $condition = "1")
{
$sql = "SELECT * FROM njoftimet WHERE $condition";
$db = new Database();
$rekordet = $db->select($sql);
// $rekordet eshte nje array me listen e rekordeve qe u kthye
$njoftimet = []; //Ky array do te mbaje listen e objekteve te tipit `Artikull`
if (count($rekordet)) {
foreach ($rekordet as $rekord) {
//Per cdo rekord te kthyer nga databaza krijojme nje objekt:
$njoftim = new Njoftim();
$njoftim->id = $rekord["id"];
$njoftim->titulli = $rekord["titulli"];
$njoftim->pershkrimi = $rekord["pershkrimi"];
$njoftim->data = $rekord["data"];
$njoftim->id_departament = $rekord["id_departament"];
// E shtojme objektin e krijuar ne array-n kryesor:
array_push($njoftimet, $njoftim);
}
//Kthejme listen e objekteve te tipit `Artikull`:
return $njoftimet;
} else {
return array();
}
}
}
- Klasa
Artikull
, e shpjeguar edhe me pare, do te sherbeje per kryerjen e veprimeve te ndryshme mbi tabelenartikujt
pra shtim, modifikim, lexim ose fshirje rekordesh me ane te metodave specifike. Implementimi i kesaj klase vijon me poshte:
<?php
require_once WEBROOT . 'libs/BaseModel.php';
class Artikull extends BaseModel
{
private $id;
public $titulli;
public $pershkrimi;
public $data;
public $id_departament;
function __construct(array $artik = [])
{
parent::__construct();
$this->titulli = isset($artik['titulli']) ? $artik['titulli'] : null;
$this->pershkrimi = isset($artik['pershkrimi']) ? $artik['pershkrimi'] : null;
$this->data = isset($artik['data']) ? $artik['data'] : null;
$this->id_departament = isset($artik['id_departament']) ? $artik['id_departament'] : null;
}
public function getId()
{
return $this->id;
}
public function save()
{
if (is_null($this->id)) {
$new_id = $this->db->insert("artikujt", [
"titulli" => $this->titulli,
"pershkrimi" => $this->pershkrimi,
"data" => $this->data,
"id_departament" => $this->id_departament
]);
return $new_id;
} else {
$rezultati = $this->db->update("artikujt", [
"titulli" => $this->titulli,
"pershkrimi" => $this->pershkrimi,
"data" => $this->data,
"id_departament" => $this->id_departament
], "id = {$this->id}");
return $rezultati;
}
}
public function delete()
{
$rezultati = $this->db->delete("artikujt", "id = {$this->id}");
return $rezultati;
}
public static function getById(int $id)
{
$sql = "SELECT * FROM artikujt WHERE id = :id";
$db = new Database();
$rekord = $db->select($sql, [":id" => $id]);
// $rekord eshte nje array me listen e rekordeve qe u kthye
if (count($rekord)) {
// Nese ekziston rekord me kete id, krijojme nje objekt perfaqesues per te
$artikull = new Artikull();
$artikull->id = $rekord[0]["id"];
$artikull->titulli = $rekord[0]["titulli"];
$artikull->pershkrimi = $rekord[0]["pershkrimi"];
$artikull->data = $rekord[0]["data"];
$artikull->id_departament = $rekord[0]["id_departament"];
return $artikull;
} else {
return null;
}
}
public static function getList(string $condition = "1")
{
$sql = "SELECT * FROM artikujt WHERE $condition";
$db = new Database();
$rekordet = $db->select($sql);
// $rekordet eshte nje array me listen e rekordeve qe u kthye
$artikujt = []; //Ky array do te mbaje listen e objekteve te tipit `Artikull`
if (count($rekordet)) {
foreach ($rekordet as $rekord) {
//Per cdo rekord te kthyer nga databaza krijojme nje objekt:
$artikull = new Artikull();
$artikull->id = $rekord["id"];
$artikull->titulli = $rekord["titulli"];
$artikull->pershkrimi = $rekord["pershkrimi"];
$artikull->data = $rekord["data"];
$artikull->id_departament = $rekord["id_departament"];
// E shtojme objektin e krijuar ne array-n kryesor:
array_push($artikujt, $artikull);
}
//Kthejme listen e objekteve te tipit `Artikull`:
return $artikujt;
} else {
return array();
}
}
}
Klasat e shpjeguara ne kete seksion perbejne te gjitha klasat e nevojshme per funksionimin e sistemit. Ajo cfare na mbetet eshte nderlidhja midis faqeve grafike te ndertuara dhe perdorimit te ketyre klasave per ta kthyer cdo gje ne dinamike. Seksioni i ardhshem do te kete si qellim perfundimin e ketij projekti duke shpjeguar sesi nje faqe HTML dhe CSS mund te kthehet ne dinamike duke perdorur klasat e mesiperme.